package com.ruyiadmin.springboot.common.utils.system;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.ruyiadmin.springboot.common.beans.system.JwtSettings;
import com.ruyiadmin.springboot.common.core.business.entities.JwtSecurityToken;
import lombok.experimental.UtilityClass;

import java.util.Calendar;
import java.util.Date;

/**
 * <p>
 * Jwt工具类
 * </p>
 *
 * @author RuYiAdmin
 * @since 2022-07-16
 */
@UtilityClass
public class RuYiJwtTokenUtil {

    //region 签发JwtToken

    /**
     * 签发JwtToken
     *
     * @param jwtSettings JwtSettings
     * @param id          预置tokenId
     * @return String token
     */
    public String createJwtSecurityToken(JwtSettings jwtSettings, String id) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, jwtSettings.getTokenExpiration());
        Date expiresDate = cal.getTime();

        return JWT.create()
                .withIssuedAt(new Date())
                .withIssuer(jwtSettings.getIssuer())
                .withAudience(jwtSettings.getAudience())
                .withExpiresAt(expiresDate)
                .withKeyId(id)
                .withClaim("sub", jwtSettings.getDefaultUser())
                .withClaim("jti", id)
                .sign(Algorithm.HMAC256(jwtSettings.getSecurityKey()));
    }

    //endregion

    //region 解析JwtToken

    /**
     * 解析JwtToken
     *
     * @param jwtSettings JwtSettings
     * @param token       jwt token
     * @return JwtSecurityToken JwtSecurityToken对象
     */
    public JwtSecurityToken verifyToken(JwtSettings jwtSettings, String token) {
        DecodedJWT decodedjwt = JWT.require(Algorithm.HMAC256(jwtSettings.getSecurityKey()))
                .build().verify(token);
        String refreshToken = decodedjwt.getKeyId();
        return new JwtSecurityToken(token, refreshToken);
    }

    public DecodedJWT decodeJwt(JwtSettings jwtSettings, String token) {
        DecodedJWT decodedjwt = JWT.require(Algorithm.HMAC256(jwtSettings.getSecurityKey()))
                .build().verify(token);
        return decodedjwt;
    }

    //endregion

}
